﻿//-----------------------------------------------------------------------
// <copyright file="MainForm.cs" company="Redmist">
//     Copyright (c) Damien T Smith. All rights reserved.
// </copyright>
// <author>Damien Smith</author>
//-----------------------------------------------------------------------

namespace Redmist.UsageMonitor.View
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Windows.Forms;
    using Redmist.UsageMonitor.Controller;
    using Redmist.UsageMonitor.CustomControls;
    using Redmist.UsageMonitor.Model;
    using Redmist.UsageMonitor.Properties;

    /// <summary>The main form or view for the application.</summary>
    public partial class MainForm : Form, IUsageView
    {
        /// <summary>A Redmist.UsageMonitor.Controller.UsageController representing a usage application controller.</summary>
        private UsageController usageController;

        /// <summary>A value indicating whether form events should be triggered.</summary>
        private bool eventsEnabled;

        /// <summary>A value indicating whether the form should close when 'Close To Tray' is enabled.</summary>
        private bool forceExit;

        /// <summary>Initializes a new instance of the MainForm class.</summary>
        public MainForm()
        {
            this.InitializeComponent();
            this.Font = ViewOperations.ResolveApplicationFont(this.Width);
            Icon appIcon = ViewOperations.RetrieveIconFile();
            this.Icon = appIcon;
            this.aboutLogoPictureBox.Image = ViewOperations.ExtractLargeIcon(appIcon);
            this.notifyIcon.Icon = new Icon(appIcon, 16, 16);
            this.openToolStripMenuItem.Font = new Font(this.Font, FontStyle.Bold);
            this.graphDaysComboBox.SelectedIndex = 2;
            this.aboutLabel.Text = string.Format(this.aboutLabel.Text, Application.ProductVersion + " beta");
            this.usageController = new UsageController(this);
        }

        /// <summary>Occurs after the view is closed.</summary>
        public event EventHandler ViewClosed;

        /// <summary>Occurs when the view requests a usage update.</summary>
        public event EventHandler UsageRequested;

        /// <summary>Occurs when the usage parameters are changed.</summary>
        public event EventHandler UsageParametersUpdated;

        /// <summary>Occurs before the view is displayed for the first time.</summary>
        public event EventHandler ViewLoad;

        /// <summary>Occurs when the NotifyIcon settings are changed.</summary>
        public event EventHandler IconSettingsChanged;

        /// <summary>Occurs when the usage update interval setting is changed.</summary>
        public event EventHandler UpdateIntervalChanged;

        /// <summary>Occurs when the usage timer interval has elapsed and the timer is enabled.</summary>
        public event EventHandler TimerElapsed;

        /// <summary>Occurs when a mouse movement is registered on a view's usage history graph.</summary>
        public event MouseEventHandler GraphMouseMoved;

        /// <summary>Gets a value indicating whether the usage history graphs should show counted rather than off peak usage.</summary>
        public bool IsGraphCountedOffPeak
        {
            get
            {
                return this.graphCountedOffPeakCheckBox.Checked;
            }
        }

        /// <summary>Gets a value indicating whether the download and upload graphs should be displayed at the same scale.</summary>
        public bool IsSharedGraphScale
        {
            get
            {
                return this.graphCommonScaleCheckBox.Checked;
            }
        }

        /// <summary>Gets or sets a System.String representing the phone number setting.</summary>
        public string PhoneNumber
        {
            get
            {
                return this.phoneNumberTextBox.Text;
            }

            set
            {
                this.phoneNumberTextBox.Text = value;
            }
        }

        /// <summary>Gets or sets a System.String representing the login password setting.</summary>
        public string Password
        {
            get
            {
                return this.passwordTextBox.Text;
            }

            set
            {
                this.passwordTextBox.Text = value;
            }
        }

        /// <summary>Gets a value representing the number of days to show on the usage history graphs.</summary>
        public int GraphHistoryDays
        {
            get
            {
                return int.Parse(this.graphDaysComboBox.Text);
            }
        }

        /// <summary>Gets the current width in pixels of the history graphs.</summary>
        public int HistoryGraphWidth
        {
            get
            {
                return this.downloadGraph.Width;
            }
        }

        /// <summary>Gets the last registered mouse X location on the usage history graphs.</summary>
        public int GraphMouseX { get; private set; }

        /// <summary>Gets or sets a Redmist.UsageMonitor.Model.IUsageModel representing the data source model.</summary>
        public IUsageModel Model
        {
            get
            {
                return this.modelBindingSource.DataSource as IUsageModel;
            }

            set
            {
                this.modelBindingSource.DataSource = value;
            }
        }

        /// <summary>Gets or sets a System.Collections.Generic.IList of Redmist.UsageMonitor.Model.HistoryViewMode representing the graph history view mode selection list.</summary>
        public IList<HistoryViewMode> HistoryViewModes
        {
            get
            {
                return this.historyViewModeBindingSource.DataSource as IList<HistoryViewMode>;
            }

            set
            {
                this.historyViewModeBindingSource.DataSource = value;
                this.graphUsageDataComboBox.SelectedIndex = 2;
            }
        }

        /// <summary>Gets a Redmist.UsageMonitor.Model.HistoryViewMode representing the currently selected graph history view mode.</summary>
        public HistoryView SelectedHistoryMode
        {
            get
            {
                return (this.graphUsageDataComboBox.SelectedItem as HistoryViewMode).HistoryView;
            }
        }

        /// <summary>Gets or sets a value representing the usage update interval in minutes.</summary>
        public int UpdateIntervalMinutes
        {
            get
            {
                return (int)this.updateIntervalNumericUpDown.Value;
            }

            set
            {
                this.updateIntervalNumericUpDown.Value = value;
            }
        }

        /// <summary>Gets or sets a value representing the usage update timer interval in milliseconds.</summary>
        public int TimerIntervalMilliseconds
        {
            get
            {
                return this.timer.Interval;
            }

            set
            {
                this.timer.Interval = value;
            }
        }

        /// <summary>Gets or sets a System.Drawing.Icon representing an icon to be displayed for a NotifyIcon.</summary>
        public Icon TrayIcon
        {
            get
            {
                return this.notifyIcon.Icon;
            }

            set
            {
                this.notifyIcon.Icon = value;
            }
        }

        /// <summary>Gets the value of the reduced off peak ratio setting.</summary>
        public int ReducedOffPeakRatio
        {
            get
            {
                return this.planSelector.SelectedOffPeakRatio;
            }
        }

        /// <summary>Gets the value of the fixed off peak quota in megabytes.</summary>
        public int FixedOffPeakQuotaMegabytes
        {
            get
            {
                return this.planSelector.FixedQuotaGigabytes * 1024;
            }
        }

        /// <summary>Gets a Redmist.UsageMonitor.CustomControls.PlanType representing the currently selected off peak plan type.</summary>
        public PlanType CurrentPlanType
        {
            get
            {
                return this.planSelector.CurrentPlanType;
            }
        }

        /// <summary>Sets the view location.</summary>
        /// <param name="point">A System.Drawing.Point representing the screen location of the view.</param>
        public void SetLocation(Point point)
        {
            this.Location = point;
        }

        /// <summary>Applies the specified settings to the view.</summary>
        /// <param name="usageSettings">A Redmist.UsageMonitor.Properties.IUsageSettings representing application settings.</param>
        public void ApplySettings(IUsageSettings usageSettings)
        {
            this.alwaysOnTopCheckBox.Checked = usageSettings.AlwaysOnTop;
            if (usageSettings.AlwaysOnTop)
            {
                this.TopMost = true;
            }

            this.closeToTrayCheckBox.Checked = usageSettings.CloseToTray;
            this.Location = new Point(usageSettings.FormLocation.X, usageSettings.FormLocation.Y);
            this.iconBackColourSelectorButton.BackColor = usageSettings.IconBackColor;
            this.iconBackColourCheckBox.Checked = usageSettings.IconBackColorEnabled;
            this.iconClearTypeCheckBox.Checked = usageSettings.IconTextClearTypeEnabled;
            this.iconTextColourSelectorButton.BackColor = usageSettings.IconTextColor;
            this.iconTextShadowColourSelectorButton.BackColor = usageSettings.IconTextShadowColor;
            this.iconTextShadowCheckBox.Checked = usageSettings.IconTextShadowEnabled;
            this.logToFileCheckBox.Checked = usageSettings.LogToFile;
            this.runMinimizedCheckBox.Checked = usageSettings.RunMinimized;
            if (usageSettings.RunMinimized)
            {
                this.WindowState = FormWindowState.Minimized;
            }
            else
            {
                this.WindowState = FormWindowState.Normal;
            }

            this.showInTaskbarCheckBox.Checked = usageSettings.ShowInTaskbar;
            this.trayNotificationsCheckBox.Checked = usageSettings.TrayNotifications;
            this.updateIntervalNumericUpDown.Value = usageSettings.UpdateInterval;
            this.loginRememberCheckBox.Checked = usageSettings.RememberLogin;
            this.planSelector.CurrentPlanType = usageSettings.PlanType;
            this.planSelector.FixedQuotaGigabytes = usageSettings.FixedOffPeakQuota;
            this.planSelector.SelectedOffPeakRatio = usageSettings.OffPeakRatio;
            this.loadOnStartupCheckBox.Checked = usageSettings.LoadOnWidowsStart;
            if (usageSettings.RememberLogin)
            {
                string[] loginDetails = Encryption.DecryptString(usageSettings.LoginDetails).Split(',');
                this.phoneNumberTextBox.Text = loginDetails[0];
                this.passwordTextBox.Text = loginDetails[1];
            }
            else
            {
                this.WindowState = FormWindowState.Normal;
                this.tabControl.SelectedTab = this.accountDetailsTabPage;
                this.phoneNumberTextBox.Select();
            }
        }

        /// <summary>Retrieves the current settings from the view.</summary>
        /// <param name="usageSettings">A Redmist.UsageMonitor.Properties.IUsageSettings representing application settings.</param>
        public void RetrieveSettings(IUsageSettings usageSettings)
        {
            usageSettings.AlwaysOnTop = this.alwaysOnTopCheckBox.Checked;
            usageSettings.CloseToTray = this.closeToTrayCheckBox.Checked;
            usageSettings.IconBackColor = this.iconBackColourSelectorButton.BackColor;
            usageSettings.IconBackColorEnabled = this.iconBackColourCheckBox.Checked;
            usageSettings.IconTextClearTypeEnabled = this.iconClearTypeCheckBox.Checked;
            usageSettings.IconTextColor = this.iconTextColourSelectorButton.BackColor;
            usageSettings.IconTextShadowColor = this.iconTextShadowColourSelectorButton.BackColor;
            usageSettings.IconTextShadowEnabled = this.iconTextShadowCheckBox.Checked;
            usageSettings.LogToFile = this.logToFileCheckBox.Checked;
            usageSettings.RunMinimized = this.runMinimizedCheckBox.Checked;
            usageSettings.ShowInTaskbar = this.showInTaskbarCheckBox.Checked;
            usageSettings.TrayNotifications = this.trayNotificationsCheckBox.Checked;
            usageSettings.UpdateInterval = (int)this.updateIntervalNumericUpDown.Value;
            usageSettings.RememberLogin = this.loginRememberCheckBox.Checked;
            usageSettings.LoginDetails = string.Empty;
            usageSettings.PlanType = this.planSelector.CurrentPlanType;
            usageSettings.FixedOffPeakQuota = this.planSelector.FixedQuotaGigabytes;
            usageSettings.OffPeakRatio = this.planSelector.SelectedOffPeakRatio;
            usageSettings.LoadOnWidowsStart = this.loadOnStartupCheckBox.Checked;
            if (this.loginRememberCheckBox.Checked)
            {
                usageSettings.LoginDetails = Encryption.EncryptString(this.phoneNumberTextBox.Text + "," + this.passwordTextBox.Text);
            }

            if (this.WindowState == FormWindowState.Minimized)
            {
                usageSettings.FormLocation = this.RestoreBounds.Location;
            }
            else
            {
                usageSettings.FormLocation = this.Location;
            }
        }

        /// <summary>Shows a usage retrieval notification on the status bar and also as a tray balloon (if enabled).</summary>
        public void ShowRetrievalInProgressMessage()
        {
            this.statusLabel.ForeColor = SystemColors.ControlText;
            this.statusLabel.Text = "Retrieving Usage Data...";

            if (this.trayNotificationsCheckBox.Checked)
            {
                this.notifyIcon.ShowBalloonTip(5000, this.Text, this.statusLabel.Text, ToolTipIcon.Info);
            }
        }

        /// <summary>Shows a timeout error message on the status bar.</summary>
        public void ShowTimeoutError()
        {
            this.statusLabel.ForeColor = Color.Red;
            this.statusLabel.Text = "#Connection Timeout";
        }

        /// <summary>Shows a connection error message on the status bar.</summary>
        public void ShowConnectionError()
        {
            this.statusLabel.ForeColor = Color.Red;
            this.statusLabel.Text = "#Connection Failed";
        }

        /// <summary>Shows an authentication error message on the status bar.</summary>
        public void ShowAuthenticationError()
        {
            this.statusLabel.ForeColor = Color.Red;
            this.statusLabel.Text = "#Incorrect Login";
            MessageBox.Show("Login Failed.  Check Phone No. & Password", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            this.tabControl.SelectedTab = this.accountDetailsTabPage;
            this.phoneNumberTextBox.Focus();
        }

        /// <summary>Shows a processing error message on the status bar.</summary>
        public void ShowProcessingError()
        {
            this.statusLabel.ForeColor = Color.Red;
            this.statusLabel.Text = "#Processing Failed";
            MessageBox.Show("There was an error processing usage data.\nIf this problem persists, please visit the aaNet web forum for assistance.", "Processing Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        /// <summary>Shows a time retrieved message on the status bar.</summary>
        public void ShowTimeRetrieved()
        {
            this.statusLabel.ForeColor = SystemColors.ControlText;
            this.statusLabel.Text = "Retrieved: " + DateTime.Now.ToString();
            if (this.trayNotificationsCheckBox.Checked)
            {
                this.notifyIcon.ShowBalloonTip(5000, this.Text, ViewOperations.CreateNotifyIconTipText(this.Model, this.CurrentPlanType), ToolTipIcon.Info);
            }
        }

        /// <summary>Changes the download history graph tooltip text.</summary>
        /// <param name="downloadToolTip">A System.String representing the text to set.</param>
        public void SetDownloadGraphToolTip(string downloadToolTip)
        {
            this.SetGraphTip(this.downloadGraph, downloadToolTip);
        }

        /// <summary>Changes the upload history graph tooltip text.</summary>
        /// <param name="uploadToolTip">A System.String representing the text to set.</param>
        public void SetUploadGraphToolTip(string uploadToolTip)
        {
            this.SetGraphTip(this.uploadGraph, uploadToolTip);
        }

        /// <summary>Starts the usage retrieval timer.</summary>
        public void StartTimer()
        {
            this.timer.Start();
        }

        /// <summary>Stops the usage retrieval timer.</summary>
        public void StopTimer()
        {
            this.timer.Stop();
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.UpdateIntervalChanged event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnUpdateIntervalChanged(EventArgs e)
        {
            if (this.UpdateIntervalChanged != null)
            {
                this.UpdateIntervalChanged(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.ViewClosed event.</summary>
        /// <param name="e">A System.Windows.Forms.FormClosedEventArgs that contains the event data.</param>
        protected virtual void OnViewClosed(FormClosedEventArgs e)
        {
            this.eventsEnabled = false;
            if (this.ViewClosed != null)
            {
                this.ViewClosed(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.GraphMouseMoved event.</summary>
        /// <param name="e">A System.Windows.Forms.MouseEventArgs that contains the event data.</param>
        protected virtual void OnGraphMouseMoved(MouseEventArgs e)
        {
            if (this.GraphMouseMoved != null)
            {
                this.GraphMouseMoved(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.UsageRequested event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnUsageUpdateRequested(EventArgs e)
        {
            if (this.UsageRequested != null)
            {
                this.UsageRequested(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.UsageParametersUpdated event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnUsageParametersUpdated(EventArgs e)
        {
            if (this.UsageParametersUpdated != null)
            {
                this.UsageParametersUpdated(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.ViewLoad event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnViewLoad(EventArgs e)
        {
            if (this.ViewLoad != null)
            {
                this.ViewLoad(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.IconSettingsChanged event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnIconSettingsChanged(EventArgs e)
        {
            if (this.eventsEnabled && this.IconSettingsChanged != null)
            {
                this.IconSettingsChanged(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.TimerElapsed event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnTimerTick(EventArgs e)
        {
            if (this.eventsEnabled && this.TimerElapsed != null)
            {
                this.TimerElapsed(this, e);
            }
        }

        /// <summary>Raises the Redmist.UsageMonitor.View.MainForm.UsageParametersUpdated event.</summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        protected virtual void OnUsageParametersChanged(EventArgs e)
        {
            if (this.eventsEnabled && this.UsageParametersUpdated != null)
            {
                this.UsageParametersUpdated(this, e);
            }
        }

        /// <summary>Adds or removes a auto run entry in the current user's registry when the 'Load on Startup' check box is toggled.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void LoadOnStartupCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (this.loadOnStartupCheckBox.Checked)
            {
                UsageRegistry.CreateAutorunEntry();
            }
            else
            {
                UsageRegistry.DeleteAutorunEntry();
            }
        }

        /// <summary>Closes the form unless the 'Close To Tray' option is enabled and the user has clicked the close button.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.forceExit || e.CloseReason != CloseReason.UserClosing)
            {
                return;
            }

            if (this.closeToTrayCheckBox.Checked)
            {
                e.Cancel = true;
                this.WindowState = FormWindowState.Minimized;
            }
        }

        /// <summary>Raises the view's usage timer tick event when the timer tick event is raised.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void Timer_Tick(object sender, EventArgs e)
        {
            this.OnTimerTick(e);
        }

        /// <summary>Raises the UsageParametersUpdated event when the GraphCountedOffPeakCheckBox is toggled.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void GraphCountedOffPeakCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (this.eventsEnabled)
            {
                this.OnUsageParametersUpdated(e);
            }
        }

        /// <summary>Raises the UsageParametersUpdated event when the GraphCommonScaleCheckBox is toggled.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void GraphCommonScaleCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            if (this.eventsEnabled)
            {
                this.OnUsageParametersUpdated(e);
            }
        }

        /// <summary>Raises the GraphMouseMoved event when the mouse is moved over the usage history graphs.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.Windows.Forms.MouseEventArgs that contains the event data.</param>
        private void Graph_MouseMove(object sender, MouseEventArgs e)
        {
            this.GraphMouseX = e.X;
            this.OnGraphMouseMoved(e);
        }

        /// <summary>Updates the values for all objects that do not support databinding.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void BindingSource_CurrentChanged(object sender, EventArgs e)
        {
            this.peakRemainingProgressBar.Minimum = 0;
            this.offPeakRemainingProgressBar.Minimum = 0;
            this.SetTip(this.billingDaysRemainingProgressBar, this.Model.FormattedNextAnniversaryToolTip);
            this.SetTip(this.billingDaysRemainingLabel, this.Model.FormattedNextAnniversaryToolTip);
            this.SetTip(this.downloadedLabel, this.Model.DownloadedToolTip);
            this.SetTip(this.uploadedLabel, this.Model.UploadedToolTip);
            this.downloadGraph.Data = this.Model.CurrentDownloadHistory;
            this.downloadGraph.Data2 = this.Model.SecondaryDownloadHistory;
            this.uploadGraph.Data = this.Model.CurrentUploadHistory;
            this.uploadGraph.Data2 = this.Model.SecondaryUploadHistory;
            NotifyIconTextFix.SetNotifyIconText(this.notifyIcon, ViewOperations.CreateNotifyIconTipText(this.Model, this.CurrentPlanType));
        }

        /// <summary>Raises the UsageParametersUpdated event when the GraphUsageDataComboBox value is changed.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void GraphUsageDataComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.eventsEnabled)
            {
                this.OnUsageParametersUpdated(e);
            }
        }

        /// <summary>Raises the UsageParametersUpdated event when the GraphDaysComboBox value is changed.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void GraphDaysComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.eventsEnabled)
            {
                this.OnUsageParametersUpdated(e);
            }
        }

        /// <summary>Sets the form's TopMost property based on the value of the 'Always On Top' checkbox.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void AlwaysOnTopCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.TopMost = this.alwaysOnTopCheckBox.Checked;
        }

        /// <summary>Sets the form's ShowInTaskbar property based on the value of the 'Show in Taskbar' checkbox and activates the form.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void ShowInTaskbarCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.ShowInTaskbar = this.showInTaskbarCheckBox.Checked;
            this.Activate();
        }

        /// <summary>Sets the form's MinimizeBox property based on the value of the 'Close to Tray' checkbox.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void CloseToTrayCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.MinimizeBox = !this.closeToTrayCheckBox.Checked;
        }

        /// <summary>Raises the ViewLoad event and enables event triggering.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.OnViewLoad(e);
            this.eventsEnabled = true;
        }

        /// <summary>Hides the form when minimized if ShowInTaskbar is disabled so that the small, resized form doesn't appear above the taskbar.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void MainForm_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                if (this.ShowInTaskbar)
                {
                    this.Visible = true;
                }
                else
                {
                    this.Visible = false;
                }
            }
            else
            {
                this.Visible = true;
            }
        }

        /// <summary>Restores the form when the notify icon is clicked with the mouse button.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void NotifyIcon_Click(object sender, EventArgs e)
        {
            if ((e as MouseEventArgs).Button == MouseButtons.Left)
            {
                this.RestoreForm();
            }
        }

        /// <summary>Enables forced exiting and closes the form.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.forceExit = true;
            this.Close();
        }

        /// <summary>Restores the form and shows the About tab.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void AboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.RestoreForm();
            this.tabControl.SelectedTab = this.aboutTabPage;
        }

        /// <summary>Restores the form.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void OpenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.RestoreForm();
        }

        /// <summary>Changes the back color of a color selector button when clicked and raises the IconSettingsChanged event.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void ColourSelectorButton_Click(object sender, EventArgs e)
        {
            Button colorSelector = sender as Button;
            this.colorDialog.Color = colorSelector.BackColor;
            if (this.colorDialog.ShowDialog() == DialogResult.OK)
            {
                colorSelector.BackColor = this.colorDialog.Color;
                this.OnIconSettingsChanged(e);
            }
        }

        /// <summary>Sets the icon shadow color selector button visibility based on the IconTextShadowCheckBox value and raises the IconSettingsChanged event.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void IconTextShadowCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.iconTextShadowColourSelectorButton.Visible = this.iconTextShadowCheckBox.Checked;
            this.OnIconSettingsChanged(e);
        }

        /// <summary>Sets the icon back color selector button visibility based on the IconBackColourCheckBox value and raises the IconSettingsChanged event.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void IconBackColourCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.iconBackColourSelectorButton.Visible = this.iconBackColourCheckBox.Checked;
            this.OnIconSettingsChanged(e);
            this.CheckClearTypeBackGround();
        }

        /// <summary>Checks the ClearType and icon background setting and raises the IconSettingsChanged event.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void IconClearTypeCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            this.CheckClearTypeBackGround();
            this.OnIconSettingsChanged(e);
        }

        /// <summary>Sets the tooltip text for the specified control.</summary>
        /// <param name="control">The System.Windows.Forms.Control to associate the ToolTip text with.</param>
        /// <param name="caption">The ToolTip text to display when the pointer is on the control.</param>
        /// <remarks>Also handles UserControls by looping through the subcontrols.</remarks>
        private void SetTip(Control control, string caption)
        {
            foreach (Control item in control.Controls)
            {
                this.toolTip.SetToolTip(item, caption);
            }

            this.toolTip.SetToolTip(control, caption);
        }

        /// <summary>Shows, restores and activates the form.</summary>
        private void RestoreForm()
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.Activate();
        }

        /// <summary>Checks if ClearType is enabled and the icon background is disabled and displays a warning.</summary>
        private void CheckClearTypeBackGround()
        {
            if (this.eventsEnabled)
            {
                if (this.iconClearTypeCheckBox.Checked && !this.iconBackColourCheckBox.Checked)
                {
                    MessageBox.Show("ClearType works best when a Back Colour is selected.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        /// <summary>Sets the tooltip for the specified graph.</summary>
        /// <param name="graph">A Redmist.UsageMonitor.CustomControls.SimpleGraph representing a graph control for which to set the tooltip.</param>
        /// <param name="caption">A System.String representing the tool tip to set for the graph.</param>
        private void SetGraphTip(SimpleGraph graph, string caption)
        {
            foreach (Control item in graph.Controls)
            {
                this.graphToolTip.SetToolTip(item, caption);
            }

            this.toolTip.SetToolTip(graph, caption);
        }

        /// <summary>Raises the view's UsageParametersChanged event when the plan selection changes.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void PlanSelector_ParametersChanged(object sender, EventArgs e)
        {
            this.OnUsageParametersChanged(e);
        }

        /// <summary>Raises the view's UsageUpdateRequested event.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void UpdateNowItem_Select(object sender, EventArgs e)
        {
            this.OnUsageUpdateRequested(e);
        }

        /// <summary>Raises the view's ViewClosed event.</summary>
        /// <param name="sender">A System.Object representing the sending object.</param>
        /// <param name="e">A System.EventArgs representing the event arguments.</param>
        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.OnViewClosed(e);
        }
    }
}
